﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
using System.Diagnostics;

namespace CamShared
{
    public class HTTPServer
    {
        private TcpListener _tcpListener = null;
        private Thread _listenThread = null;

        public event HTTPClient.RequestHandler OnRequest;
        public int Port { get; set; }
        public HTTPServer(int Port)
        {
            this.Port = Port;
        }

        public void Start()
        {
            if (_listenThread != null)
            {
                throw new Exception("Already called Start");
            }

            _tcpListener = new TcpListener(Port);
            _tcpListener.Start();

            _listenThread = new Thread(ListenThreadEntry);
            _listenThread.Start();
        }

        private void ListenThreadEntry()
        {
            while (_tcpListener.Server.IsBound)
            {
                try
                {
                    TcpClient tcpConnection = _tcpListener.AcceptTcpClient();
                    ThreadPool.QueueUserWorkItem(new WaitCallback(_ConnectionThreadEntry), tcpConnection);
                }
                catch (Exception)
                {
                    // no need to handle errors.
                }
            }
        }

        private void _ConnectionThreadEntry(object otcp)
        {
            HTTPClient h = new HTTPClient((TcpClient)otcp);
            h.OnRequest += new HTTPClient.RequestHandler(h_OnRequest);
            h.ReadRequest();
        }

        public string LocalEndPoint
        {
            get
            {
                IPHostEntry host;
                host = Dns.GetHostEntry(Dns.GetHostName());
                foreach (IPAddress ip in host.AddressList)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork
                        && !ip.ToString().StartsWith("127"))
                    {
                        return ip.ToString();
                    }
                }
                return Dns.GetHostName();
            }
        }

        void h_OnRequest(HTTPClient client, string url, string method, string body)
        {
            if (OnRequest != null)
            {
                try
                {
                    OnRequest.Invoke(client, url, method, body);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine("Error at OnRequest: " + ex);
                }
            }
        }
    }
}
